﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NHibernate;
using Pcme.Info.MvcMusicStore.Helpers;
using NHibernate.Criterion;

namespace Pcme.Info.MvcMusicStore.Models
{
    public partial class ShoppingCart
    {
        ISession session = NHibernateHelper.GetSession();
        string shoppingCartId { get; set; }
        public const string CartSessionKey = "CartId";

        public static ShoppingCart GetCart(HttpContextBase context)
        {
            var cart = new ShoppingCart();
            cart.shoppingCartId = cart.GetCartId(context);
            return cart;
        }

        public void AddToCart(Album album)
        {
            var cartItem = session.CreateQuery("from Cart c Where c.CartId=:cid and c.Album.AlbumId=:aid")
                .SetString("cid", shoppingCartId)
                .SetInt32("aid", album.AlbumId)
                .UniqueResult<Cart>();

            if (cartItem == null)
            {
                // Create a new cart item
                cartItem = new Cart
                {
                    Album = album,
                    CartId = shoppingCartId,
                    Count = 1,
                    DateCreated = DateTime.Now
                };
                //storeDB.AddToCarts(cartItem);
            }
            else
            {
                // Add one to the quantity
                cartItem.Count++;
            }

            // Save it
            session.SaveOrUpdate(cartItem);
            session.Flush();
        }

        public void RemoveFromCart(int id)
        {
            //Get the cart
            var cartItem = session.CreateQuery("from Cart c Where c.CartId=:cid and c.RecordId=:rid")
                .SetString("cid", shoppingCartId)
                .SetInt32("rid", id)
                .UniqueResult<Cart>();

            if (cartItem != null)
            {
                if (cartItem.Count > 1)
                {
                    cartItem.Count--;
                }
                else
                {
                    session.Delete(cartItem);
                }
                session.Flush();
            }
        }

        public void EmptyCart()
        {
            var cartItems = session.CreateQuery("from Cart c Where c.CartId=:cid")
                .SetString("cid", shoppingCartId)
                .List<Cart>();

            foreach (var cartItem in cartItems)
            {
                session.Delete(cartItem);
            }

            session.Flush();
        }

        public IList<Cart> GetCartItems()
        {
            var cartItems = session.CreateQuery("from Cart c Where c.CartId=:cid")
                .SetString("cid", shoppingCartId)
                .List<Cart>();
            return cartItems;
        }

        public int GetCount()
        {
            /*int? count = (from cartItems in storeDB.Carts
                          where cartItems.CartId == shoppingCartId
                          select (int?)cartItems.Count).Sum();*/

            long? count = session.CreateQuery("select sum(c.Count) from Cart c where c.CartId=:cid")
                .SetString("cid", shoppingCartId)
                .UniqueResult<long>();

            return (int)(count ?? 0);
        }

        public decimal GetTotal()
        {
            /*decimal? total =
                (from cartItems in storeDB.Carts
                 where cartItems.CartId == shoppingCartId
                 select (int?)cartItems.Count * cartItems.Album.Price)
                .Sum();*/

            decimal? total = session.CreateQuery("select sum(c.Count*c.Album.Price) from Cart c where c.CartId=:cid")
                .SetString("cid", shoppingCartId)
                .UniqueResult<decimal>();

            return total ?? decimal.Zero;
        }

        public int CreateOrder(Order order)
        {
            decimal orderTotal = 0;

            var cartItems = GetCartItems();

            //Iterate the items in the cart, adding Order Details for each
            foreach (var cartItem in cartItems)
            {
                var orderDetails = new OrderDetail
                {
                    Album = cartItem.Album,
                    Order = order,
                    UnitPrice = cartItem.Album.Price
                };

                session.Save(orderDetails);

                orderTotal += (cartItem.Count * cartItem.Album.Price);
            }

            //Save the order
            session.Flush();

            //Empty the shopping cart
            EmptyCart();

            //Return the OrderId as a confirmation number
            return order.OrderId;
        }

        // We're using HttpContextBase to allow access to cookies.
        public String GetCartId(HttpContextBase context)
        {
            if (context.Session[CartSessionKey] == null)
            {
                if (!string.IsNullOrEmpty(context.User.Identity.Name))
                {
                    // User is logged in, associate the cart with there username
                    context.Session[CartSessionKey] = context.User.Identity.Name;
                }
                else
                {
                    // Generate a new random GUID using System.Guid Class
                    Guid tempCartId = Guid.NewGuid();

                    // Send tempCartId back to client as a cookie
                    context.Session[CartSessionKey] = tempCartId.ToString();
                }
            }
            return context.Session[CartSessionKey].ToString();
        }

        // When a user has logged in, migrate their shopping cart to
        // be associated with their username
        public void MigrateCart(string userName)
        {
            var shoppingCart = session.CreateCriteria<Cart>()
                .Add(Restrictions.Eq("CartId", shoppingCartId))
                .List<Cart>();

            foreach (Cart item in shoppingCart)
            {
                item.CartId = userName;
            }
            session.Flush();
        }
    }
}